@isTest
private class Account_TestLeadContactCount {

    static testMethod void LeadMassTest(){
    	// Create 201 Accounts
    	List<Account> TestAccounts = new List<Account>();
    	for(Integer i = 0; i<200; i++){
    		TestAccounts.add(new Account(Name='Account '+i));
    	}
    	insert TestAccounts;
    	
    	// Create a set of the Account Ids
    	Set<Id> AccountIDs = new Set<Id>();
    	
    	// Create a Lead for each Account
    	List<Lead> TestLeads = new List<Lead>();
    	for(Account a : TestAccounts){
    		TestLeads.add(new Lead(LastName='Smith',Company='Test ',Account__c=a.Id,Status='Targeted', Lead_Status__c = 'New'));
    		AccountIDs.add(a.Id);
    	}
    	
    	// Create a Contact for each Account
    	List<Contact>TestContacts = new List<Contact>();
    	for(Account a : TestAccounts){
    		TestContacts.add(new Contact(LastName='Smith',AccountID=a.Id, Status__c = 'New'));
    	}
    	
    	// Insert the Leads and Contacts. This is where the governer test is
    	test.starttest();
    	LeadSync_AsyncApex.firstCount=true; // Reset this so it'll update the count again.
    	insert TestLeads;
    	LeadSync_AsyncApex.firstCount=true; // Reset this so it'll update the count again.
    	insert TestContacts;
    	test.stoptest();
    	
    	// Verify that the Lead and Contact Counts are correct.
    	TestAccounts = [select Leads__c,Contacts__c from Account where Id in :AccountIDs];
    	Double CountDifference = 0;
    	for(Account a : TestAccounts){
    		CountDifference += a.Leads__c + a.Contacts__c - 2; // There should be one of each, so this should add 0
    	}
    	System.AssertEquals(0,CountDifference);
    }
    
    static testMethod void AddLead() {
        // Create an Account
        Account AcctA = new Account(Name='Account A',Status__c='Targeted');
        insert AcctA;
        
        // Create a Lead at that Account
        Lead TestLead = new Lead(LastName='Smith', Company='Test',Account__c = AcctA.Id, Status='Targeted',Lead_Status__c = 'New');
        test.starttest();
        insert TestLead;
        test.stoptest();
        
        // Verify that Lead Count is 1
        System.AssertEquals(1,[select Leads__c from Account where Id = :AcctA.Id].Leads__c);
    }
    
    static testMethod void DeleteLead() {
        // Create an Account
        Account AcctA = new Account(Name='Account A',Status__c='Targeted');
        insert AcctA;
        
        // Create a Lead at that Account
        Lead TestLead = new Lead(LastName='Smith', Company='Test',Account__c = AcctA.Id, Status='Targeted',Lead_Status__c = 'New');
        
        insert TestLead;
        
        // Delete Lead
        test.starttest();
        LeadSync_AsyncApex.firstCount=true; // Reset this so it'll update the count again.
        delete TestLead;
        test.stoptest();
        
        // Verify that Lead Count is 0
        System.AssertEquals(0,[select Leads__c from Account where Id = :AcctA.Id].Leads__c);
    }
    
    static testMethod void UndeleteLead() {
        // Create an Account
        Account AcctA = new Account(Name='Account A',Status__c='Targeted');
        insert AcctA;
        
        // Create a Lead at that Account
        Lead TestLead = new Lead(LastName='Smith', Company='Test',Account__c = AcctA.Id, Status='Targeted',Lead_Status__c = 'New');
        test.starttest();
        insert TestLead;
        
        // Delete Lead
        delete TestLead;
        
        // UnDelete Lead
        
        undelete TestLead;
        test.stoptest();
        
        // Verify that Lead Count is 1
        System.AssertEquals(1,[select Leads__c from Account where Id = :AcctA.Id].Leads__c);
    }
    
    static testMethod void ChangeLeadAccount() {
        // Create an Account
        Account AcctA = new Account(Name='Account A',Status__c='Targeted');
        insert AcctA;
        
        // Create a Lead at that Account
        Lead TestLead = new Lead(LastName='Smith', Company='Test',Account__c = AcctA.Id, Status='Targeted',Lead_Status__c = 'New');
        
        insert TestLead;
        
        // Create another Account (B)
        Account AcctB = new Account(Name='Account B',Status__c='Targeted');
        insert AcctB;
        
        // Change account field on Lead to Account B
        TestLead.Account__c = AcctB.Id;
        LeadSync_AsyncApex.firstCount=true; // Reset this so it'll update the count again.
        test.starttest();
        update TestLead;
        test.stoptest();
        
        // Verify that Lead Count on Account A is 0 and Account B is 1
        System.AssertEquals(0,[select Leads__c from Account where Id = :AcctA.Id].Leads__c);
        System.AssertEquals(1,[select Leads__c from Account where Id = :AcctB.Id].Leads__c);
    }
    
    
    
    static testMethod void AddContact(){
    	// Create an Account
    	Account AcctA = new Account(Name='Account A');
        insert AcctA;
        
        // Create a Contact at that Account
        Contact TestContact = new Contact(LastName='Smith', AccountID = AcctA.Id, Status__c = 'New');
        test.starttest();
        insert TestContact;
        test.stoptest();
        
        // Verify that Contact Count is 1
        System.AssertEquals(1,[select Contacts__c from Account where Id = :AcctA.Id].Contacts__c);
    }
    
    static testMethod void DeleteContact(){
    	// Create an Account
    	Account AcctA = new Account(Name='Account A');
        insert AcctA;
        
        // Create a Contact at that Account
        Contact TestContact = new Contact(LastName='Smith', AccountID = AcctA.Id, Status__c = 'New');
        insert TestContact;
        
        // Delete Contact
        LeadSync_AsyncApex.firstCount=true; // Reset this so it'll update the count again.
        test.starttest();
        delete TestContact;
        test.stoptest();
        
        // Verify that Contact Count is 0
        System.AssertEquals(0,[select Contacts__c from Account where Id = :AcctA.Id].Contacts__c);
        
    }
    
    static testMethod void UndeleteContact(){
    	// Create an Account
    	Account AcctA = new Account(Name='Account A');
        insert AcctA;
        
        // Create a Contact at that Account
        Contact TestContact = new Contact(LastName='Smith', AccountID = AcctA.Id, Status__c = 'New');
        insert TestContact;
        
        // Delete Contact
        delete TestContact;
        
        // UnDelete Contact
        test.starttest();
        undelete TestContact;
        test.stoptest();
        
        // Verify that Contact Count is 1
        System.AssertEquals(1,[select Contacts__c from Account where Id = :AcctA.Id].Contacts__c);
        
    }
    
    static testMethod void ChangeContactAccount(){
    	// Create an Account
    	Account AcctA = new Account(Name='Account A');
        insert AcctA;
        
        // Create a Contact at that Account
        Contact TestContact = new Contact(LastName='Smith', AccountID = AcctA.Id, Status__c = 'New');
        insert TestContact;
        
        // Create another Account (B)
        Account AcctB = new Account(Name='Account B');
        insert AcctB;
        
        // Change account field on Contact to Account B
        TestContact.AccountID = AcctB.Id;
        test.starttest();
        LeadSync_AsyncApex.firstCount=true; // Reset this so it'll update the count again.
        update TestContact;
        test.stoptest();
        
        // Verify that Contact Count on Account A is 0 and Account B is 1
        System.AssertEquals(0,[select Contacts__c from Account where Id = :AcctA.Id].Contacts__c);
        System.AssertEquals(1,[select Contacts__c from Account where Id = :AcctB.Id].Contacts__c);
    }
    
    
    
 
}